<?php
require_once dirname ( __FILE__ ) . '/DaoBase.php';
require_once dirname ( __FILE__ ) . '/../Generic.php';
require_once dirname ( __FILE__ ) . '/../DbConnect.php';
abstract class DaoBaseImpl extends DbConnect implements DaoBase {
	
	// class properties
	protected $table;
	
	// constructor
	function __construct($table_name) {
		// parent initial
		parent::__construct ();
		parent::connect ();
		
		// prepare instance object
		$this->table = DbConnect::PREFIX . $table_name;
	}
	function refValues($arr) {
		if (strnatcmp ( phpversion (), '5.3' ) >= 0) {
			$refs = array ();
			foreach ( $arr as $key => $value )
				$refs [$key] = &$arr [$key];
			return $refs;
		}
		return $arr;
	}
	public function getType($obj) {
		if (is_string ( $obj )) {
			return "s";
		} else if (is_int ( $obj )) {
			return "i";
		} else if (is_float ( $obj )) {
			return "d";
		}
	}
	public function create($domain) {
		$fields = $domain->field;
		if (empty ( $fields )) {
			throw new Exception ( "Fields can't empty" );
		}
		$query = "INSERT INTO " . $this->table;
		$query .= "(";
		$columns = array_keys ( $fields );
		$values = array_values ( $fields );
		
		// detect columns from domain
		$strVal = "";
		$bindParams = "";
		$size = count ( $columns );
		for($i = 0; $i < $size; $i ++) {
			$query .= $columns [$i];
			$strVal .= "?";
			$obj = $values [$i];
			
			// detect data type for param statement
			$bindParams .= $this->getType ( $obj );
			
			// detect need coma or not
			if ($i < $size - 1) {
				$query .= ", ";
				$strVal .= ", ";
			}
		}
		$query .= ") values ";
		
		// detect values from domain
		$query .= "(";
		$query .= $strVal;
		$query .= ")";
		
		// prepare statement
		$stmt = $this->conn->prepare ( $query );
		call_user_func_array ( array (
				$stmt,
				'bind_param' 
		), $this->refValues ( array_merge ( array (
				$bindParams 
		), $values ) ) );
		$return = $stmt->execute ();
		if ($return) {
			$return = ENTITY_CREATED_SUCCESSFULLY;
		} else {
			$domain->error = true;
			$domain->error_message = $stmt->error;
			$return = ENTITY_CREATE_FAILED;
		}
		$stmt->close ();
		return $return;
	}
	public function get($id) {
		$query = "SELECT * FROM " . $this->table . " WHERE id = ?";
		$stmt = $this->conn->prepare ( $query );
		$stmt->bind_param ( $this->getType ( $id ), $id );
		$stmt->execute ();
		$meta = $stmt->result_metadata ();
		while ( $column = $meta->fetch_field () ) {
			$bindVarsArray [] = &$results [$column->name];
		}
		call_user_func_array ( array (
				$stmt,
				'bind_result' 
		), $bindVarsArray );
		
		while ( $stmt->fetch () ) {
			$find [] = $results;
		}
		$stmt->close ();
		return $find;
	}
	public function find($domain) {
		$query = "SELECT * FROM " . $this->table;
		$stmt = $this->conn->prepare ( $query );
		$stmt->execute ();
		$meta = $stmt->result_metadata ();
		while ( $column = $meta->fetch_field () ) {
			$bindVarsArray [] = &$results [$column->name];
		}
		call_user_func_array ( array (
				$stmt,
				'bind_result' 
		), $bindVarsArray );
		
		while ( $stmt->fetch () ) {
			$find [] = $results;
		}
		$stmt->close ();
		return $find;
	}
	public function delete($id) {
		$query = "DELETE FROM " . $this->table . " WHERE id = ?";
		$stmt = $this->conn->prepare ( $query );
		$stmt->bind_param ( $this->getType ( $id ), $id );
		$return = $stmt->execute ();
		$return = true;
		if ($return) {
			$return = true;
		} else {
			$return = false;
		}
		$stmt->close ();
		return $return;
	}
}
?>